/**
 * @file    sop_calc.c
 * @brief   服务层-计算SOP值
 * @author  name
 * @version 1.0.1
 * @date    2023-04-28
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-28 <td>1.0.1     <td>name     <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "sop_calc.h"
#include "var_mng.h"
#include "param_mng.h"
#include "diagnosis.h"
#include "cfg_prj.h"

/* macro/define --------------------------------------------------------------*/
#define CHG_SOP_RELEASE_DLY         (60000)
/* typedef -------------------------------------------------------------------*/

/* local functions -----------------------------------------------------------*/

/* static variables ----------------------------------------------------------*/
static uint8_t sop_chg_step = 0;
static uint32_t chg_release_delay = 0;
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief  计算SOP中的充电电流与放电电流需求
 * @param  cycle: 计算周期
 * @return
*/   
void sop_calc(uint16_t cycle)
{
	uint16_t max_volt = 0;
	uint16_t base_chg_curr = 0;
	uint16_t base_dsg_curr = 0;
	uint16_t sop_cc = 0;
	uint16_t sop_dc = 0;
	uint16_t cov_param = 0;
	uint16_t sop_volt_cc = 0;
	uint16_t sop_temp_cc = 0;
	uint16_t sop_occ_cc = 0;	
	uint16_t func_cfg = 0;
	
	max_volt = var_get_data(VAR_ID_MAX_CELL_VOLT);
	
	base_chg_curr = param_get_data(PAR_ID_SOP_CC);
	base_dsg_curr = param_get_data(PAR_ID_SOP_DC);

	// 非充电状态下 , 静态30S，解除充电限制 
	if(var_get_data(VAR_ID_CURR_DR) != CURR_DR_CHG)
	{
		chg_release_delay += cycle;
		if(chg_release_delay >= CHG_SOP_RELEASE_DLY)
		{
			sop_chg_step = 0;
			chg_release_delay = 0;
		}
	}
	else
	{
		chg_release_delay = 0;
	}
	// 温度告警类限流为一般需求
	if(diag_get_alarm(ALM_ID_OTC) || diag_get_alarm(ALM_ID_UTC) || diag_get_alarm(ALM_ID_OTE)
		   ||diag_get_alarm(ALM_ID_UTE) || diag_get_alarm(ALM_ID_OTM) ) 
	{
		sop_temp_cc = 0.5 * base_chg_curr;
	}
	else 
	{
		sop_temp_cc = base_chg_curr;
	}
    //充电过流保护限流伟10A需求
    if(diag_get_prp(PRP_ID_OCC)||diag_get_prp(PRP_ID_OCC2))
	{
	   sop_occ_cc = 0.25 * base_chg_curr;	
	}
	else 
	{
	   sop_occ_cc = base_chg_curr;
	}
	// 保护类-除充电过流保护，限流为10A，其他类限流为0A
   if(diag_get_alarm(ALM_ID_COV) || diag_get_alarm(ALM_ID_BOV) || diag_get_prp(PRP_ID_FULL_CHG)
		|| diag_get_alarm(ALM_ID_FCHG)||diag_get_prp(PRP_ID_BOV) || diag_get_prp(PRP_ID_COV)
		||diag_get_prp(PRP_ID_OTC) || diag_get_prp(PRP_ID_OTE) || diag_get_prp(PRP_ID_OTM)
		||diag_get_prp(PRP_ID_VDIFF))
	{
		sop_cc = 0;
	}
   else if(diag_get_prp(PRP_ID_UTE) || diag_get_prp(PRP_ID_UTC))
	{
		param_get_2bits_val(PAR_ID_FUNC_CFG ,FUNC_HOT_POS , &func_cfg); 
		if(PARAM_FUNC_CFG_EN == func_cfg)
		{
		    sop_cc = 100;				
		}
		else
		{	
		    sop_cc	= 0;
		}		
	}

	// 故障类
   else if(diag_get_prp(PRP_ID_COL) || diag_get_prp(PRP_ID_TOL) || diag_get_prp(PRP_ID_FT_AFE)
	   ||diag_get_prp(PRP_ID_FT_CMOS) || diag_get_prp(PRP_ID_FT_DMOS))
	{
		sop_cc = 0;
	}
	else
	{
		cov_param = param_get_data(PAR_ID_COV_ALM_VAL);
		if(max_volt < cov_param - 150)
		{                
			if(sop_chg_step < 1)
			{
				sop_chg_step = 0;
			}
		}
		else if(max_volt < cov_param - 100)
		{                                             
			if(sop_chg_step <= 1)
			{
				sop_chg_step = 1;
			}
		}
		else if(max_volt < cov_param - 50)
		{                                             
			if(sop_chg_step <= 2)
			{
				sop_chg_step = 2;
			}
		}
		else
		{
			 sop_chg_step = 3;
		}

		switch(sop_chg_step)
		{
			case 0:
				sop_volt_cc = 1.0 * base_chg_curr;
				break;
			case 1:
				sop_volt_cc = 0.5 * base_chg_curr;
				break;
			case 2:
				sop_volt_cc = 0.2 * base_chg_curr;
				break;
			case 3:
				sop_volt_cc = 0.1 * base_chg_curr;
				break;
			default:
				sop_volt_cc = 0.1 * base_chg_curr;
				break;
		}
	sop_cc = sop_temp_cc;
	if(sop_cc > sop_occ_cc)
		sop_cc = sop_occ_cc;
	if(sop_cc > sop_volt_cc)
		sop_cc = sop_volt_cc;		
				
	if(sop_cc < 100)
		sop_cc = 100;
	}
	// 放电限流策略
	if((var_get_data(VAR_ID_MOS_STATE) & (1 << VAR_MOS_ST_DSG)))
	{
		if(diag_get_alarm(ALM_ID_CUV) || diag_get_alarm(ALM_ID_BUV)
		   ||diag_get_alarm(ALM_ID_OTD) || diag_get_alarm(ALM_ID_UTD) || diag_get_alarm(ALM_ID_OTE)
		   ||diag_get_alarm(ALM_ID_UTE) || diag_get_alarm(ALM_ID_OTM) || diag_get_alarm(ALM_ID_OCD))
		{
			sop_dc = 0.5 * base_dsg_curr;
		}
		else
		{
			if(var_get_data(VAR_ID_MIN_CELL_VOLT) >= 2700)
			{
				sop_dc = base_dsg_curr;
			}
			else
			{
				sop_dc = 0;
			}
		}
	}
	else
	{
		sop_dc = 0;
	}
    
	var_set_data(VAR_ID_SOP_CC , sop_cc);
	var_set_data(VAR_ID_SOP_DC , sop_dc);
	
	var_set_data(VAR_ID_SOP_CV , sop_calc_cv());
	
    var_set_data(VAR_ID_SOP_DV , sop_calc_dv());
}

uint16_t sop_calc_cv(void)
{
    return param_get_data(PAR_ID_SOP_CV);
}

uint16_t sop_calc_dv(void)
{
    return param_get_data(PAR_ID_SOP_DV);
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
 
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/


